package server;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import message.Message;
import message.MessageParser;
import message.types.stalker.LoginSuccessAnswer;
import message.types.string.LoginRequest;
import message.types.stringstring.LoginFailedAnswer;
import message.types.unique.EmptyMessage;
import network.e2e.FrameReader;
import network.e2e.FrameWriter;
import network.link.FrameInputStream;
import network.link.FrameOutputStream;
import stalker.Stalker;
import stalker.user.User;

/**
 * Handles user initial login request
 */

public class LoginManager implements Runnable {
  
  private final Socket socket_;
  
  public LoginManager(Socket socket) {
    assert socket != null;
    socket_ = socket;
  }

  public void run() {
    OutputStream os = null;
    InputStream is = null;
    try {
      os = socket_.getOutputStream();
      is = socket_.getInputStream();
      
      FrameReader reader = new FrameReader(new FrameInputStream(is));
      FrameWriter writer = new FrameWriter(new FrameOutputStream(os));
      while (true) {
        //retrieve first login message
        Message init_message = MessageParser.retrieve(reader);
        if (init_message instanceof EmptyMessage) {
          break;
        }
        if (init_message instanceof LoginRequest) {
          //good.
          System.out.println("Login Request detected");
          LoginRequest log_req = (LoginRequest)init_message;
          System.out.println(log_req);
          if (User.isTaken(log_req.getName())) {
            System.out.println("User already present");
            if (User.getUserFromName(log_req.getName()).isLoggedIn()) {
              //name already taken
              System.out.println("Bad!");
              MessageParser.send(
                  new LoginFailedAnswer(
                      Stalker.LOGIN_MANAGER_STALKER, 
                      Stalker.GUEST_STALKER, log_req.getName(), 
                      "Username already present"
                      ), 
                  writer);
              writer.flush();
              continue;
            }
          }
          // name is good
          User new_user = null;
          System.out.println("Good!");
          if (User.isTaken(log_req.getName())) {
            new_user = User.getUserFromName(log_req.getName());
          } else {
            new_user = User.createUser(log_req.getName());
          }
          System.out.println("Succeed!");
          MessageParser.send(new LoginSuccessAnswer(Stalker.LOGIN_MANAGER_STALKER, new_user, new_user), writer);
          writer.flush();
          new_user.activate(reader, writer);
          break;
        } else {
          socket_.close();
          break;
        }
      }
    } catch (IOException e) {
      System.out.println("Stream error");
    }
  }
}
